use crate::features::quizzes::ddd::QuizSnapshot;
use crate::features::quizzes::modelsdbo::{QuizDBO, QuizItemDBO};
use crate::features::sgraph::{self};
use crate::features::tasks::{self};
use rbatis::crud::{Skip, CRUD};
use rbatis::rbatis::Rbatis;

// 通过 id 获取试卷Quiz
pub async fn get_quiz_by_id(rbatis_pool: &Rbatis, id: &str) -> Result<QuizDBO, rbatis::Error> {
  let id_wrapper = rbatis_pool.new_wrapper().eq("id", id);
  let quiz = rbatis_pool.fetch_by_wrapper::<QuizDBO>(id_wrapper).await;

  quiz
}

// 通过 id 获取试题QuizItem
pub async fn get_quiz_item_by_id(rbatis_pool: &Rbatis, id: &str) -> Result<QuizItemDBO, rbatis::Error> {
  let id_wrapper = rbatis_pool.new_wrapper().eq("id", id);
  let quiz_item_dbo = rbatis_pool.fetch_by_wrapper::<QuizItemDBO>(id_wrapper).await;

  quiz_item_dbo
}


// 通过 id 获取 子试题QuizItem
#[py_sql(
  rbatis,
  "SELECT q.* FROM quizitems q 
   WHERE e.master_id=#{quiz_id}"
)]
pub async fn get_quiz_item_by_master_id(
  rbatis: &Rbatis,
  quiz_id: &str,
) -> Option<Vec<QuizItemDBO>> {
  todo!()
}

#[py_sql(
  rbatis,
  "SELECT q.* FROM quizitems q 
   INNER JOIN edges e ON q.id=e.subject 
   WHERE e.predicate='MEMBER' AND e.object=#{quiz_id}"
)]
pub async fn select_quiz_items_by(
  rbatis: &Rbatis,
  quiz_id: &str,
) -> Option<Vec<QuizItemDBO>> {
  todo!()
}


pub async fn upsert_snapshot(
  rbatis_pool: &Rbatis,
  snapshot: &QuizSnapshot,
) -> Result<u64, rbatis::Error> {
  let mut succ_count = 0;
  let mut err = false;
  
  // 1. no need to update QuizDBO


  // 2. upsert edgedbo
  for edge in &snapshot.edges {
    let rs = sgraph::services::upsert_edgedbo(rbatis_pool, edge).await;
    if rs.is_ok() {
      succ_count += 1;
    } else {
      err = true;
      break;
    }
  }
  // 3. upsert taskdbo
  if err == false {
    for task in &snapshot.tasks {
      let rs = tasks::repository::upsert_task(rbatis_pool, task).await;
      if rs.is_ok() {
        succ_count += 1;
      } else {
        err = true;
        break;
      }
    }
  }

  if err {
    Err(rbatis::Error::E(format!(
      "could not upsert snapshot={:?}",
      snapshot
    )))
  } else {
    Ok(succ_count)
  }
}
